<?php
class KarmayogaAssignment_Controller extends AdminController {

    public $REGISTRATION_LIST_UUID = 'admin/karmayogaAssignment/registrationList';
    
    /** @var KarmayogaAssignmentData */
    public $data;

    public function __construct() {
        parent::__construct('registration');
        $this->setDefaultListOrder('id');
        
        $this->data = $this->getSessionData()->getKarmayogaAssignmentData();
    }
    
    /**
     * Entry method - initializes the session data.
     */
    public function init() {
    	$seminarId = $this->input->get('seminar_id');
    	
    	// Basic validation
    	if (! valid::isId($seminarId)) {
    		$this->redirectToList('error.invalidId');
    	}
    	
    	$seminar = $this->dao->fetchSeminar($seminarId, $this->getL10nLanguageCode());
    	if (! $seminar) {
    		$this->redirectToList('error.recordNotFound');
    	}
    	
    	// Create session data object
    	$this->data = new KarmayogaAssignmentData();
    	$this->getSessionData()->setKarmayogaAssignmentData($this->data);
    	$this->data->seminar = $seminar;
    	
    	
    	$this->redirectToForm();
    }
    
    public function form() {
    	$this->viewData['settingsFormData'] = array();
    	if ($this->data->batchList) {
    		$this->viewData['settingsFormData']['batch_codes'] = array_keys($this->data->batchList);
    	}
    	$this->viewData['seminar'] = $this->data->seminar;
    	$this->viewData['batchList'] = $this->data->batchList;
    	
    	$this->loadFormData();
    
    	$this->renderSubview('/admin/karmayogaAssignment/karmayogaAssignmentForm');
    }
    
    protected function loadFormData() {
    	$seminarId = $this->data->seminar['id'];
    	
    	// Unassigned karmayoga registrations
    	$this->viewData['registrationList'] = $this->findRegistrations($seminarId, null);
    	
    	$this->viewData['karmayogaTypeOptions'] = $this->dao->queryOptions(
    			'SELECT l10n.karmayoga_type_code, l10n.name ' .
    			'FROM karmayoga_type_l10n l10n ' .
    			'WHERE l10n.language_code = :lang ' .
    			'ORDER BY l10n.name',
    			array('lang' => $this->getL10nLanguageCode()));
    	$this->viewData['karmayogaTypeOptions'] = array_merge(array('' => ''), $this->viewData['karmayogaTypeOptions']);
    	
    	// Already assigned karmayoga types
    	$params = array('seminar_id' => $this->data->seminar['id'], 'lang' => $this->getL10nLanguageCode());
    	$query = 'SELECT karmayoga_type_code AS code, name ' .
    			'FROM karmayoga_type_l10n l10n ' .
    			'WHERE l10n.language_code = :lang ' .
    			'AND l10n.karmayoga_type_code IN (' .
    				'SELECT assigned_karmayoga_type_code ' .
    				'FROM registration ' .
    				'WHERE assigned_karmayoga_type_code IS NOT NULL ' .
    				'AND cancelled_at IS NULL ' .
    				'AND seminar_id = :seminar_id ';
    	if ($this->data->batchList) {
    		$batchCodeList = array_keys($this->data->batchList);
    		$query .= 'AND batch_code IN (' . sql::inClauseValues($batchCodeList) . ')';
    	}
    	$query .= ')';
    	$this->viewData['usedKarmayogaTypeList'] = $this->dao->queryAll($query, $params);
    	
    	foreach ($this->viewData['usedKarmayogaTypeList'] as &$karmayogaType) {
    		$karmayogaType['registrationList'] = $this->findRegistrations($seminarId, $karmayogaType['code']);
    	}
    	
    	// Batch options for the selected seminar - only those where there are some KY registrations
    	$this->viewData['batchOptions'] = $this->dao->queryOptions(
    			'SELECT b.batch_code, l10n.name, b.batch_code ' .
    			'FROM batch b ' .
    			'JOIN batch_l10n l10n ON l10n.seminar_id = b.seminar_id AND l10n.batch_code = b.batch_code AND l10n.language_code = :lang ' .
    			'WHERE b.seminar_id = :seminar_id ' .
    			'AND b.batch_code IN (' .
    				'SELECT batch_code FROM registration r JOIN category c ON c.seminar_id = r.seminar_id AND c.category_code = r.category_code ' .
    				'WHERE r.seminar_id = :seminar_id AND c.program_type_code = :kyCode AND r.cancelled_at IS NULL)' .
    			'ORDER BY b.begin_date, b.end_date DESC',
    			array('seminar_id' => $seminarId, 'kyCode' => constants::$programTypeCodeKarmayoga, 'lang' => $this->getL10nLanguageCode()),
    			'()');
    }
    
    public function assignOne() {
    	$formData = $_REQUEST;
    	$registrationId = $formData['registration_id'];
    	$karmayogaTypeCode = $formData['karmayoga_type_code'];
    
    	$seminarId = $this->data->seminar['id'];
    
    	$registration = $this->dao->getById('registration', $registrationId);
    	$registration['assigned_karmayoga_type_code'] = $karmayogaTypeCode ? $karmayogaTypeCode : NULL;
    	$this->dao->update('registration', $registration);
    
    	$this->redirectToForm();
    }
    
    public function assignSelected() {
    	$formData = $this->postToDbValues();
    	$karmayogaTypeCode = $formData['karmayoga_type_code'];
    	$registrationIdList = $formData['registration_ids'];
    
    	$seminarId = $this->data->seminar['id'];
    
    	if ($registrationIdList) {
    		foreach ($registrationIdList as $registrationId) {
    			$registration = $this->dao->getById('registration', $registrationId);
    			$registration['assigned_karmayoga_type_code'] = $karmayogaTypeCode ? $karmayogaTypeCode : NULL;
    			$this->dao->update('registration', $registration);
    		}
    	}
    
    	$this->redirectToForm();
    }

    public function saveSettings() {
    	// List of batch IDs is empty if we just came from seminarDisplay page
    	$batchCodeList = $this->input->post('batch_codes');
    	
    	$this->data->batchList = array();
    	
    	if ($batchCodeList && is_array($batchCodeList)) {
    		foreach ($batchCodeList as $batchCode) {
		    	if (valid::isCode($batchCode)) {
		    		$batch = $this->dao->getLocalizedBatch($this->data->seminar['id'], $batchCode, $this->getL10nLanguageCode());
		    		if ($batch) {
		    			$this->data->batchList[$batch['batch_code']] = $batch;
		    		}
		    	}
    		}
    	}
    	
    	$this->redirectToForm();
    }
    
    private function redirectToForm() {
    	$this->redirect('/admin/karmayogaAssignment/form');
    }
    
    protected function redirectToList($errorKey=NULL) {
        if ($errorKey) {
            $this->msg->error($errorKey);
        }
        $this->redirect('/admin/seminar/all');
    }
    
    /**
     * Finds registrations with the given karmayoga type.
     */
    private function findRegistrations($seminarId, $karmayogaTypeCode) {
        $params = array(
        		'lang' => $this->getL10nLanguageCode(), 
        		'karmayogaCode' => constants::$programTypeCodeKarmayoga,
        		'seminar_id' => $seminarId
        );
        $query = 'SELECT reg.*, ' .
    			'per.first_name, per.last_name, per.birth_date, per.email, per.idcard_number, per.street, per.city, per.postal_code, per.notes AS person_notes, per.gender, ' .
		    	'c.code AS country_code, c.name_native AS country_name, ' .
		    	'at.name AS accomodation_type_name, ' .
		    	'b.begin_date, b.end_date, ' .
		    	'org.name payment_organization_name, ' .
		    	'pkl10n.name AS preferred_karmayoga_type_name ' .
		    	'FROM registration reg ' .
		    	'JOIN category cat ON cat.category_code = reg.category_code AND cat.seminar_id = reg.seminar_id ' .
		    	'JOIN batch b ON b.seminar_id = reg.seminar_id AND reg.batch_code = b.batch_code ' .
		    	'LEFT OUTER JOIN person per ON per.id = reg.person_id ' .
		    	'LEFT OUTER JOIN country c ON per.country_of_residence_code = c.code ' .
		    	'LEFT OUTER JOIN accomodation_type_l10n at ON at.accomodation_type_code = cat.accomodation_type_code AND at.language_code = :lang ' .
		    	'LEFT OUTER JOIN organization org ON org.id = reg.payment_organization_id ' .
		    	'LEFT OUTER JOIN karmayoga_type_l10n pkl10n ON reg.preferred_karmayoga_type_code = pkl10n.karmayoga_type_code AND pkl10n.language_code = :lang ' .
    			'WHERE cat.program_type_code = :karmayogaCode ' .
    			'AND reg.cancelled_at IS NULL ' .
    			'AND reg.seminar_id = :seminar_id ';
        if ($this->data->batchList) {
        	$batchCodeList = array_keys($this->data->batchList);
        	$query .= 'AND reg.batch_code IN (' . sql::inClauseValues($batchCodeList) . ') ';
        }
        if ($karmayogaTypeCode) {
            $query .= 'AND reg.assigned_karmayoga_type_code = :karmayoga_type_code ';
            $params['karmayoga_type_code'] = $karmayogaTypeCode;
        }
        else {
        	$query .= 'AND reg.assigned_karmayoga_type_code IS NULL ';
        }
        $query .= 'ORDER BY per.last_name, per.first_name';
        
        return $this->dao->queryAll($query, $params);
    }
}
